#ifdef I2C

#ifdef I2C_SLAVE
unsigned long userPluginEventBuffer = 0;
#else
#ifdef I2C_MASTER
unsigned long userPluginEventBuffer = 0;
#endif
#endif

#ifdef I2C_MASTER
byte userPluginI2CTargetSlaveID = 0;
#endif

#ifdef I2C_POLLING
byte userPluginI2CPollSlaveID = 0;
#endif

/*********************************************************************************************\ 
 * Dit deel van de plugin wordt eenmalig aangeroepen direct na boot en tonen welkomsttekst
 \*********************************************************************************************/
void UserPlugin_I2C_Init(void)
{
#ifdef I2C_SLAVE
  #ifdef NODO_CLASSIC
  #else
    Wire.begin(Settings.Unit);  // re-init wire interface with slave address
  #endif
    Wire.onRequest(requestEvent); // register function to process in case of data request by master
    Wire.onReceive(receiveEvent); // register function to process in case data received from master
#endif
}

void UserPlugin_I2C_Command(int Par1, int Par2)
{
#ifdef I2C_MASTER
  if (Par1 == 8)
  {
    userPluginI2CTargetSlaveID = Par2;
  }
#endif

#ifdef I2C_POLLING
  if (Par1 == 210) userPluginI2CPollSlaveID = Par2;
#endif

#ifdef I2C_MASTER
  if (Par1 == 240)
  {
    Wire.beginTransmission(32);   //Begin the transmission to PCF8574
    Wire.write(Par2);             //Send the data to PCF8574
    Wire.endTransmission();
  }
  if (Par1 == 241)
  {
    Wire.requestFrom(32,1); 
    if(Wire.available())     //If the request is available
    {
      Serial.println((int)Wire.read());   //Receive the data
    }
  }
  if (Par1 == 250) wire_get(Par2);
  if (Par1 == 251)
  {
    byte unit = (userPluginEventBuffer >> 24) & 0xf;
    byte command = (userPluginEventBuffer >> 16) & 0xff;
    if ((command != CMD_USERPLUGIN) && (unit != Par2)) wire_put(Par2); // do not send userplugin or events that came from target
  }
  if (Par1 == 252)
  {
#ifdef NODO_CLASSIC
    userPluginEventBuffer = command2event(CMD_USER_EVENT, 255, 255);
#else
    userPluginEventBuffer = command2event(Settings.Unit, CMD_USEREVENT, 255, 255);
#endif
    wire_put(Par2);
  }
#endif
}

boolean UserPlugin_I2C_Receive(unsigned long Event)
{

  byte code=0;

#ifdef I2C_SLAVE
  userPluginEventBuffer = Event;
#else
#ifdef I2C_MASTER
  userPluginEventBuffer = Event;
#endif
#endif
  // funktie kan op twee manieren worden verlaten:
  // true = Nodo gaat verder met verwerking van het event
  // false = Event wordt niet verder behandeld.
  if (code == 0) return true;
  return false;
}

void UserPlugin_I2C_Periodically()
{
#ifdef I2C_POLLING
  if(Queue.Position == 0) if(userPluginI2CPollSlaveID != 0) wire_get(userPluginI2CPollSlaveID);
#endif

#ifdef NODO_CLASSIC
  // Verwerk de events die in de queue zijn geplaatst
  if(QueuePos)
  {
    userPluginPrintTerminal("Periodic Queue!"); 
    for(byte x=0;x<QueuePos;x++)
    {
      PrintText(Text_08);
      PrintEvent(QueueEvent[x],QueuePort[x],VALUE_DIRECTION_INPUT);  // geef event weer op Serial
      ProcessEvent2(QueueEvent[x],VALUE_DIRECTION_INPUT,QueuePort[x],0,0);      // verwerk binnengekomen event.
    }
    QueuePos=0;
  }
#else
  // Verwerk de events die in de queue zijn geplaatst
  if(Queue.Position)
  {
    userPluginPrintTerminal("Periodic Queue!"); 
    for(byte x=0;x<Queue.Position;x++)
    {
      PrintEvent(Queue.Event[x],Queue.Port[x],VALUE_DIRECTION_INPUT);  // geef event weer op Serial
      ProcessEvent2(Queue.Event[x],VALUE_DIRECTION_INPUT,Queue.Port[x],0,0);      // verwerk binnengekomen event.
    }
    Queue.Position=0;
  }
#endif

  return;
}

/*********************************************************************************************\
 * I2C stuff, get data from slave
 \*********************************************************************************************/
#ifdef I2C_MASTER
void wire_get(byte address)
{
  unsigned long tempEvent=0;
  byte I2CByte=0;

  Wire.requestFrom(address, (byte)4);    // request 4 bytes from slave device

  if (Wire.available() == 4) for(byte x=0; x<4; x++)
  {
#ifdef ARDUINO_0022
    I2CByte= (byte)Wire.receive();
#else
    I2CByte= (byte)Wire.read();
#endif
    tempEvent = tempEvent | (((unsigned long)I2CByte) << (8*x) );
  }

  if (tempEvent != 0)
  {
    Serial.print("I2C Event by request:");
    Serial.println(tempEvent);
    userPluginSendEvent(tempEvent);
    //PrintEvent(tempEvent,VALUE_SOURCE_SYSTEM,VALUE_DIRECTION_INPUT);  // geef event weer op Serial
    //SendHTTPEvent(tempEvent);
#ifdef UDP_BROADCAST
    userPluginUDPPrintEvent(tempEvent);
#endif
    //ProcessEvent2(tempEvent,VALUE_DIRECTION_INPUT,VALUE_SOURCE_SYSTEM,0,0);
  }
}

/*********************************************************************************************\
 * I2C stuff, send data to slave
 \*********************************************************************************************/
void wire_put(byte address)
{
  byte I2CByte[4];

  //Serial.print("I2C Put Event:");
  //Serial.println(userPluginEventBuffer);

  Wire.beginTransmission(address);
  for(byte x=0; x<4; x++)
  {
    I2CByte[x] = (byte)(userPluginEventBuffer >> (x * 8) & 0xff);
  }
#ifdef ARDUINO_0022
  Wire.send(I2CByte,4);
#else
  Wire.write(I2CByte,4);
#endif

  Wire.endTransmission();
}
#endif

/*********************************************************************************************\
 * I2C stuff, data request by master
 \*********************************************************************************************/
#ifdef I2C_SLAVE
void requestEvent()
{
  byte I2CByte[4];
  byte activeVar = 0;
  unsigned long tempEvent=0;

  while( (UserVar[activeVar] == 32767) && (activeVar < 15))
  {
    activeVar++;
  }

  if (activeVar < 15)
  {
    tempEvent=AnalogInt2event(UserVar[activeVar], activeVar+1, CMD_VARIABLE_EVENT);
    UserVar[activeVar] = 32767;
  }

  if (tempEvent == 0)
  {
    tempEvent = userPluginEventBuffer;
    userPluginEventBuffer=0;
  }

  for(byte x=0; x<4; x++)
  {
    I2CByte[x] = (byte)(tempEvent >> (x * 8) & 0xff);
  }
#ifdef ARDUINO_0022
  Wire.send(I2CByte,4);
#else
  Wire.write(I2CByte,4);
#endif
}

/*********************************************************************************************\
 * I2C stuff, data received from Master
 \*********************************************************************************************/
void receiveEvent(int bytes)
{
  // This is an interrupt driven routine, keep processing time as low as possible
  // do not user serial debugging commands
  unsigned long tempEvent=0;
  byte I2CByte=0;

  if (Wire.available() == 4) for(byte x=0; x<4; x++)
  {
#ifdef ARDUINO_0022
    I2CByte= (byte)Wire.receive();
#else
    I2CByte= (byte)Wire.read();
#endif
    tempEvent = tempEvent | (((unsigned long)I2CByte) << (8*x) );
  }

  if (tempEvent != 0)
  {
#ifdef NODO_CLASSIC
    if(QueuePos<EVENT_QUEUE_MAX)
    {
      QueueEvent[QueuePos]=tempEvent;
      QueuePort[QueuePos]=VALUE_SOURCE_SYSTEM;
      QueuePos++;           
    }
#else
    if(Queue.Position<EVENT_QUEUE_MAX)
    {
      Queue.Event[Queue.Position]=tempEvent;
      Queue.Port[Queue.Position]=VALUE_SOURCE_RF;
      Queue.Position++;
    }
#endif    
  }
}
#endif

/*********************************************************************************************\ 
 * Send userplugin event data
 \*********************************************************************************************/
void userPluginSendEvent_I2C(unsigned long Event)
{

#ifdef I2C_MASTER
  if (userPluginSendMode == 3)
  {
    userPluginEventBuffer = Event;
    wire_put(userPluginI2CTargetSlaveID);
    delay(10);
  }
#endif

}

#endif

